package com.cennavi.mineplay.gisfile;

import java.io.File;
import java.nio.charset.Charset;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.vividsolutions.jts.io.WKTWriter;

public class MifReader {

	private List<String> columnNames = new ArrayList<>();
	private List<String> columnTypes = new ArrayList<>();

	private String tableName;

	private Connection conn;

	private MifMidReader reader;

	public MifReader(String mifPath, Connection conn, String tableName)
			throws Exception {

		File file = new File(mifPath);

		this.conn = conn;

		this.tableName = tableName;

		Charset charset = Charset.forName("UTF-8");

		reader = new MifMidReader(file, charset);

		reader.createIndexes();

		Map<String, String> map = reader.getColumns();

		Iterator<Entry<String, String>> it = map.entrySet().iterator();

		while (it.hasNext()) {
			Entry<String, String> en = it.next();
			columnNames.add(en.getKey());
			columnTypes.add(en.getValue());
		}

	}

	public void createTable() throws Exception {

		StringBuilder sqlSB = new StringBuilder("create table ");
		sqlSB.append(tableName);
		sqlSB.append("(geom geometry");
		for (int i = 0; i < columnNames.size(); i++) {
			String column = columnNames.get(i);
			String type = columnTypes.get(i);

			sqlSB.append(",");
			sqlSB.append(column);
			if ("INTEGER".equals(type)) {
				sqlSB.append(" int");
			} else if ("DOUBLE".equals(type)) {
				sqlSB.append(" numeric");
			} else {
				sqlSB.append(" character varying(1000)");
			}
		}
		sqlSB.append(")");
		Statement stmt = conn.createStatement();
		stmt.execute(sqlSB.toString());
		stmt.close();

	}

	public void batchInsert() throws Exception {

		StringBuilder sql = new StringBuilder("insert into ");
		sql.append(tableName);
		sql.append("(geom");
		for (int i = 0; i < columnNames.size(); i++) {
			sql.append(",");
			sql.append(columnNames.get(i));
		}
		sql.append(") values (st_geomfromtext(?,4326)");
		for (int i = 0; i < columnNames.size(); i++) {
			sql.append(",?");
		}
		sql.append(")");

		int rows = reader.getFeatureNumber();

		PreparedStatement pstmt = conn.prepareStatement(sql.toString());

		for (int i = 0; i < rows; i++) {

			pstmt.setString(1, new WKTWriter().write(reader.getGeometry(i)));

			Object[] values = reader.getValues(i);

			for (int j = 0; j < values.length; j++) {
				String type = columnTypes.get(j);
				if ("INTEGER".equals(type)) {
					pstmt.setLong(j + 2, (Long) values[j]);
				} else if ("DOUBLE".equals(type)) {
					pstmt.setDouble(j + 2, (Double) values[j]);
				} else {
					Object v = values[j];
					if (v != null) {
						if (v.toString().length() > 300)
							pstmt.setString(j + 2,
									v.toString().substring(0, 300));
						else
							pstmt.setString(j + 2, v.toString());
					} else {
						pstmt.setString(j + 2, null);
					}
				}
			}

			pstmt.addBatch();

			if (i % 501 == 0)
				pstmt.executeBatch();
		}

		pstmt.executeBatch();

		pstmt.close();
	}

//	public static void main(String[] args) throws Exception {
//
//		Class.forName("org.postgresql.Driver");
//
//		Connection conn = DriverManager.getConnection(
//				"jdbc:postgresql://36.111.84.170:5442/mineplay", "postgres",
//				"cennavi2018");
//
//		test t = new test("c:/vt-pbf/wh.mif", conn, "wh");
//
//		t.createTable();
//
//		t.batchInsert();
//	}
}
